package main

import "fmt"

// 数组切片map
func main() {
	//数组的声明和初始化数组是具有相同 唯一类型 的一组以编号且长度固定的数据项序列（这是一种同构的数据结构）；
	//这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。
	//数组长度必须是一个常量表达式，并且必须是一个非负整数。数组长度也是数组类型的一部分，所以 [5] int 和 [10] int 是属于不同类型的。数组的编译时值初始化是按照数组顺序完成的

	//数组的声明格式  var name [len]type
	var array1 [3]int
	//赋值1
	array1 = [3]int{1, 2, 3} //赋值的每一个元素都必须时同一种数据类型

	//声明并赋值
	var array2 = [...]int{1, 2, 3} //数组的长度可以被...忽略

	var array3 [3]int
	//赋值2
	array3[0] = 1
	array3[1] = 2
	array3[2] = 3
	var array4 = [...]int{0: 1, 1: 2, 2: 3}
	fmt.Println(array1, array2, array3, array4)

	array1[0] = 0 //对索引项为 i 的数组元素赋值可以这么操作：arr[i] = value，所以数组是 可变的
	fmt.Println(array1, array2, array3, array4)

	//由于索引的存在，遍历数组的方法自然就是使用 for 结构:
	for i := 0; i < len(array1); i++ {
		fmt.Printf("array[%d]=%d\n", i, array1[i])
	}

	//也可以使用range
	for i, v := range array1 { //i是下标，v是值
		fmt.Printf("array[%d]=%d\n", i, v)
	}

	//Go 语言中的数组是一种 值类型 所以可以通过 new() 来创建： var arr1 = new([5]int)
	var arr1 = new([3]int) //此时new出来的对象，arr1是指针类型，指向这块地址，而不是数组类型
	arr1[0] = 1
	arr1[1] = 2
	arr1[2] = 3
	println(arr1) //此时输出的是一个地址
	println(arr1[1])
	var arr2 [3]int //这样定义出来的对象他就是数组类型，而不是指针类型
	arr2 = *arr1
	arr2[1] = 0 //此时改变这里的值，由于arr2他是数组类型，他有自己的地址，因此不会影响到arr1, 如果你想修改原数组，那么 arr2 必须通过 & 操作符以引用方式传过来
	println(arr2[1])
	println(arr1[1])

	//数组通常是一维的，但是可以用来组装成多维数组，例如：[3][5]int，[2][2][2]float64。
	//内部数组总是长度相同的。Go 语言的多维数组是矩形式的

	//把一个大数组传递给函数会消耗很多内存。有两种方法可以避免这种现象：
	//传递数组的指针
	array := [3]float64{7.0, 8.5, 9.1}
	x := Sum(&array) // Note the explicit address-of operator
	// to pass a pointer to the array
	fmt.Printf("The sum of the array is: %f", x)
	//使用数组的切片
}
func Sum(a *[3]float64) (sum float64) {
	for _, v := range *a { // *a代表地址a对应的值
		sum += v
	}
	return sum
}
